﻿using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace ST.Common.Util.Mvc
{
    public class BaseService
    {
        /// <summary>
        /// 获取请求的IP地址
        /// </summary>
        /// <returns></returns>
        protected virtual string GetRequestIP()
        {
            return HttpContextHelper.GetRequestIP();
        }

        /// <summary>
        /// 格式化对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        protected string FormatObject(object obj)
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(obj, new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore
            });
        }

        public List<T> ExecuteReaderWithinTrans<T>(DbConnection conn, DbTransaction trans, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.StoredProcedure) where T : new()
        {
            List<T> lst = new List<T>();
            var cmd = conn.CreateCommand();
            cmd.Transaction = trans;
            cmd.CommandText = sql;
            cmd.CommandType = cmdType;
            if (parameters != null && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }
            using (DbDataReader dr = cmd.ExecuteReader())
            {
                var columns = dr.GetColumnSchema();
                List<string> lstColumn = new List<string>();
                foreach (var col in columns)
                {
                    lstColumn.Add(col.ColumnName);
                }
                while (dr.Read())
                {
                    T m = new T();
                    PropertyInfo[] properties = m.GetType().GetProperties();
                    foreach (PropertyInfo pi in properties)
                    {
                        if (pi.CanWrite && lstColumn.Contains(pi.Name))
                        {
                            // 判断此属性是否有Setter
                            object value = dr[pi.Name];
                            if (value != DBNull.Value)
                                pi.SetValue(m, value, null);
                        }
                    }
                    lst.Add(m);
                }
            }
            return lst;
        }

        public DataTable ExecuteReaderWithinTrans(DbConnection conn, DbTransaction trans, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.Text)
        {
            DataTable dt = new DataTable();
            var cmd = conn.CreateCommand();
            cmd.Transaction = trans;
            cmd.CommandText = sql;
            cmd.CommandType = cmdType;
            if (parameters != null && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }
            using (var dr = cmd.ExecuteReader())
            {
                dt.Load(dr);
            }
            return dt;
        }

        public object ExecuteScalar(DbContext ctx, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.Text)
        {
            throw new NotImplementedException();
            //object ret = null;
            //using (var cmd = ctx.Database.GetDbConnection().CreateCommand())
            //{
            //    cmd.CommandText = sql;
            //    cmd.CommandType = cmdType;
            //    if (parameters != null && parameters.Length > 0)
            //    {
            //        cmd.Parameters.AddRange(parameters);
            //    }
            //    ctx.Database.OpenConnection();
            //    ret = cmd.ExecuteScalar();
            //    ctx.Database.CloseConnection();
            //}
            //return ret;
        }

        public object ExecuteScalarWithinTrans(DbConnection conn, DbTransaction trans, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.Text)
        {
            DataTable dt = new DataTable();
            var cmd = conn.CreateCommand();
            cmd.Transaction = trans;
            cmd.CommandText = sql;
            cmd.CommandType = cmdType;
            if (parameters != null && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }
            return cmd.ExecuteScalar();
        }

        public int ExecuteNonQueryWithinTrans(DbConnection conn, DbTransaction trans, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.Text)
        {
            var cmd = conn.CreateCommand();
            cmd.Transaction = trans;
            cmd.CommandText = sql;
            cmd.CommandType = cmdType;
            if (parameters != null && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }
            return cmd.ExecuteNonQuery();
        }

        public object ExecuteNonQuery(DbContext ctx, string sql, DbParameter[] parameters, CommandType cmdType = CommandType.Text)
        {
            throw new NotImplementedException();
            //int ret;
            //using (var cmd = ctx.Database.GetDbConnection().CreateCommand())
            //{
            //	cmd.CommandText = sql;
            //	cmd.CommandType = cmdType;
            //	if (parameters != null && parameters.Length > 0)
            //	{
            //		cmd.Parameters.AddRange(parameters);
            //	}
            //	ctx.Database.OpenConnection();
            //	ret = cmd.ExecuteNonQuery();
            //	ctx.Database.CloseConnection();
            //}
            //return ret;
        }
    }
}
